/**
 * [v-loading指令]
 * 使用v-loading="loading"
 * loading文案loading-text="Loading..."
 * loading大小可直接传loading-size="'small' | 'default' | 'large'"
 * loading背景色可直接传loading-background="rgba(255,255,255,0.1)"
 */

import { needSetPosition } from '@/utils'
import { Spin } from 'ant-design-vue'
import { h, render, type ObjectDirective } from 'vue'

type Size = 'small' | 'default' | 'large'

function appendLoading(element: HTMLElement) {
	if (needSetPosition(window.getComputedStyle(element).position) && needSetPosition(element.style.position)) {
		element.style.position = 'relative'
	}
	const wrap = document.createElement('div')
	wrap.id = 'v-loading'
	const tip = element.getAttribute('loading-tip') || ''
	const size = (element.getAttribute('loading-size') as Size) || 'default'
	const loadingBackground = element.getAttribute('loading-background') || 'default'
	loadingBackground && (wrap.style.background = loadingBackground)
	const vnode: VNode = h(Spin, { tip, size })
	render(vnode, wrap)
	element.appendChild(wrap)
}

function removeLoading(element: HTMLElement) {
	const wrap = element.querySelector('#v-loading')
	wrap && element.removeChild(wrap)
}

const loading: ObjectDirective<HTMLElement, boolean> = {
	mounted(element, binding) {
		if (binding.value) {
			appendLoading(element)
		}
	},

	updated(element, binding) {
		if (binding.value !== binding.oldValue) {
			binding.value && appendLoading(element)
			!binding.value && removeLoading(element)
		}
	}
}

export default loading
